<?php

namespace app\client\controller\say;

use app\common\controller\Frontend;
use app\common\enums\LearnMeansEnum;
use app\common\enums\say\StrangeTypeEnum;
use app\common\model\banxi\Grade;
use app\common\model\banxi\learn\LearnSayQuestionAnswerRecord;
use app\common\model\banxi\learn\LearnSayQuestionRecord;
use app\common\model\banxi\learn\LearnSayReviewRecord;
use app\common\model\banxi\learn\LearnSayReviewSentenceRecord;
use app\common\model\banxi\learn\LearnSkRecord;
use app\common\model\banxi\organization\Organization;
use app\common\model\banxi\say\SayTeachSentence;
use app\common\model\banxi\student\StudentSaySentence;
use app\common\service\learn\LearnSkRecordService;
use app\common\service\yunzisheng\HivoiceEvalService;
use ba\Exception;
use think\db\exception\PDOException;
use think\exception\ValidateException;
use think\facade\Db;

class Question extends Frontend
{
    protected array $noNeedLogin = [];

    protected array $noNeedPermission = ['*'];

    public function initialize(): void
    {
        parent::initialize();
    }

    /**
     * 学习列表
     */
    public function listQuestionData()
    {
        $param = $this->request->param(['index', 'limit', 'orderBy', "query"]);
        $studentId = $this->auth->id;
        $param['query']['EQ_studentId'] = $studentId;
        $param['query']['EQ_isSubmit'] = 1;
        //查询条件解析
        $where = get_query($param);
        //获取分页数据
        $pageParams = get_page_params($param);

        $LearnSayVocabularyRecordModel = new LearnSayQuestionRecord();
        $list = $LearnSayVocabularyRecordModel->where($where)
            ->order(['id' => 'desc'])
            ->field('id,skRecordId,learnMeans,sayTeachSentenceName,answerStartTime,answerDuration,rightNum,errorNum,useTime')
            ->paginate([
                'page' => $pageParams['page'],
                'list_rows' => $pageParams['limit']
            ]);
        $this->ok('ok', result_row($list));
    }

    /**
     * 开始学习
     */
    public function startQuestion()
    {
        $teachSentenceId = $this->request->post('teachSentenceId');
        $skRecordId = null;
        $trainerId = null;
        $studentId = $this->auth->id;
        $learnMeans = LearnMeansEnum::E2; // 默认为练习模式（对应 LearnMeans.E2）
        // 如果提供了上课记录ID
        $LearnSkRecordService = new LearnSkRecordService();
        $result = $LearnSkRecordService->startSayQuestion($skRecordId, $studentId, $trainerId, $learnMeans, $teachSentenceId);
        if (!$result) {
            $this->fail($LearnSkRecordService->getError());
        }
        $this->ok('ok', $result);
    }

    /**
     * 提交答案
     */
    public function answerQuestion()
    {
        $recordId = $this->request->post('recordId', null);
        $answerList = $this->request->filter('')->post('answerList');
        if (!$answerList) {
            $this->fail('提交答案不能为空');
        }
        $trainerId = null;
        $studentId = $this->auth->id;
        $LearnSkRecordService = new LearnSkRecordService();
        $result = $LearnSkRecordService->answerSayQuestion($recordId, $trainerId, $studentId, $answerList);
        if (!$result) {
            $this->fail($LearnSkRecordService->getError());
        }
        $this->ok('ok', $result);
    }

    /**
     * 口语评测
     */
    public function readEval()
    {
        $content = $this->request->post('content', '','trim');
        $voiceUrl = $this->request->post('voiceUrl', '');
        if (!$content) {
            $this->error('缺少跟读内容');
        }
        if (!$voiceUrl) {
            $this->error('缺少跟读语音');
        }

        $hivoiceEvalService = new HivoiceEvalService();
        $response = $hivoiceEvalService->evalMp3($content,$voiceUrl);
        $words_list = $response['lines'][0]['words'];
        $sub_words_list = [];
        foreach ($words_list as $wordInfo) {
            if (empty(trim($wordInfo['text']))) {
                continue;
            }
            $sub_words_list[] = [
                'text' => $wordInfo['text'],
                'score' => bcMath($wordInfo['score'], 10, '*')
            ];
        }

        // 计算语速(每分钟单词数)
        $pronunciationTime = $response['lines'][0]['end']; // 发音用时(秒)
        $wordCount = count($sub_words_list);
        $minutes = ceil($pronunciationTime) / 60; // 转换为分钟
        $wordsPerMinute = $minutes > 0 ? ceil($wordCount / $minutes) : 0;

        $result = [
            'score' => $response['score'],
            'fluency' => $response['lines'][0]['fluency'],
            'integrity' => $response['lines'][0]['integrity'],
            'pronunciation' => $response['lines'][0]['pronunciation'],
            'end' => $pronunciationTime,
            'per_minute_words' => $wordsPerMinute,
            'short_sentence' => $content,
            'sub_words_list' => $sub_words_list
        ];
        $this->ok('短句评测', $result);
    }

    /**
     * 获取学习报告
     */
    public function getSayQuestionReport()
    {
        $questionRecordId = $this->request->get('questionRecordId');
        if (!$questionRecordId) {
            $this->fail('请选择学习记录');
        }

        $LearnSkRecordService = new LearnSkRecordService();
        $result = $LearnSkRecordService->questionReport($questionRecordId);

        $this->ok('ok',$result );
    }

    /**
     * 设置掌握状态
     */
    public function setCorrectStatus()
    {
        $answerRecordId = $this->request->param('recordId');
        $isCorrect = $this->request->param('isCorrect');
        if (!in_array($isCorrect, [1, 0])) {
            $this->fail('请选择是否掌握');
        }
        $type = $this->request->param('type');//1学习3复习
        switch ($type) {
            case 1:
                //学习
                $recordModel = new LearnSayQuestionRecord();
                $answerModel = new LearnSayQuestionAnswerRecord();
                break;
            case 3:
                //复习
                $recordModel = new LearnSayReviewRecord();
                $answerModel = new LearnSayReviewSentenceRecord();
            default:
                $this->fail('不支持的类型');
        }
        $info = $answerModel->where(['id' => $answerRecordId])->find();
        if (empty($info)) {
            $this->fail('记录不存在');
        }
        $recordInfo = $recordModel->where(['id' => $info['recordId']])->field('id,rightNum,errorNum,rightRate')->find();
        if (empty($recordInfo)) {
            $this->fail('学习记录不存在');
        }
        Db::startTrans();
        try {
            if ($info['isCorrect'] != $isCorrect) {
                $info->isCorrect = $isCorrect;
                $info->save();
                $totalNum = $recordInfo['rightNum'] + $recordInfo['errorNum'];
                $rightNum = $isCorrect == 1 ? $recordInfo['rightNum'] + 1 : $recordInfo['rightNum'] - 1;
                $errorNum = $isCorrect == 1 ? $recordInfo['errorNum'] - 1 : $recordInfo['errorNum'] + 1;
                $correctRate = $totalNum > 0 ? intval(($rightNum / $totalNum) * 100) : 0;
                $recordInfo->rightNum = $rightNum;
                $recordInfo->errorNum = $errorNum;
                $recordInfo->rightRate = $correctRate;
                $recordInfo->save();
            }
            if (!empty($info['studentId'])) {
                $sentence = [
                    'studentId' => $info['studentId'],
                    'sayTeachSentenceId' => $info['sayTeachSentenceId'],
                    'strangeType' => StrangeTypeEnum::E1,
                    'sentenceEn' => $info['sentenceEn'],
                    'sentenceZh' => $info['sentenceZh'],
                    'sentencePhonetic' => $info['sentencePhonetic'],
                    'sentenceAudio' => $info['sentenceAudio'],
                    'sentenceImage' => $info['sentenceImage'],
                    'sentenceWordColor' => $info['sentenceWordColor'],
                    'isCorrect' => $isCorrect
                ];
                $StudentSaySentenceModel = new StudentSaySentence();
                $StudentSaySentenceModel->updateStudentSentence($info['studentId'], $sentence, $type);
            }
            Db::commit();
        } catch (Exception|PDOException|ValidateException $e) {
            Db::rollback();
            $this->fail('fail');
        }

        $this->ok('ok');
    }

    //随声听播放列表
    public function listListenSound()
    {
        $params = $this->request->param(['index', 'limit', 'recordId'=>'']);
        $pageParams = get_page_params($params);
        $studentId = $this->auth->id;
        $learnSayQuestionAnswerRecordModel = new LearnSayQuestionAnswerRecord();
        $list = $learnSayQuestionAnswerRecordModel->alias('a')
            ->where([
                ['studentId', '=', $studentId],
                ['isCorrect', '>', -1],
            ])->whereExists(function ($query) use ($params) {
                $subquery = $query->name('banxi_learn_say_question_record')
                    ->whereColumn('a.recordId', 'id')
                    ->where('learnMeans', LearnMeansEnum::E1)
                    ->where('del', 0);
                if ($params['recordId']) {
                    $subquery->where('id', $params['recordId']);
                }
                return $subquery;
            })->field('id,sentenceEn,sentenceZh,sentenceAudio')
            ->order(['parentTeachSentenceId' => 'asc'])
            ->paginate([
                'page' => $pageParams['page'],
                'list_rows' => $pageParams['limit'],
            ]);
        $this->ok('ok', result_row($list));
    }
}